package one.stand.controller;

import com.google.common.collect.Lists;
import com.jmp.api.crm.dto.OrderDownloadResponse;
import com.jmp.api.crm.dto.OrdersInfoResponse;
import com.jmp.api.crm.dto.OrdersSendRequest;
import com.jmp.autocofiguration.web.interceptor.SecurityAuthCheck;
import com.jmp.base.dto.*;
import com.jmp.feign.OrderFeign;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import one.stand.advice.ResultEnum;
import one.stand.dto.Company2Dto;
import one.stand.dto.ConvertUtils;
import one.stand.dto.UserDto;
import one.stand.enums.OrderStateEnum;
import one.stand.model.BusinessCard;
import one.stand.model.ResultModel;
import one.stand.request.OrdersRequest;
import one.stand.service.BusinessCardBaseService;
import one.stand.service.CompanyBaseService;
import one.stand.service.user.UserAdminService;
import one.stand.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单信息
 *
 * @author
 */
@Controller
@RequestMapping("crmPc/orders")
public class OrdersController extends BaseController {

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private BusinessCardBaseService businessCardBaseService;
    @Autowired
    private CompanyBaseService companyBaseService;

    @ApiOperation(value = "根据公司查询订单(订单状态（1待付款，2待发货，3待收货，4已完成，5交易取消，6退款成功）)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "createTimes", value = "下单时间", paramType = "String"),
            @ApiImplicitParam(name = "orderState", value = "订单状态（1待付款，2待发货，3待收货，4已完成，5交易取消，6退款成功）", required = true, paramType = "Integer"),
    })
    @PostMapping("/selectOrdersInfoPc")
    @ResponseBody
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<OrderListPcResponse> selectOrdersInfoPc(@RequestAttribute OrdersRequest request) {
        RequestContext.User user = RequestContextHolder.getRequestContext().getUser();
        OrderListPcRequest listPcRequest = OrderListPcRequest.builder()
                .companyId(user.getCompanyId())
                .orderState(request.getOrderState())
                .createTimes(request.getCreateTimes())
                .build();
        listPcRequest.setPageNum(request.getPageNum());
        ResultModel<OrderListPcResponse> responseResultModel = orderFeign.listPc(listPcRequest);
        AssertUtil.isTrue(responseResultModel);

        return responseResultModel;
    }

    @ApiOperation(value = "查询订单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ordersId", value = "订单id", required = true, paramType = "Integer"),
    })
    @PostMapping("/getOrdersInfo")
    @ResponseBody
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<List<OrdersInfoResponse>> getOrdersInfo(@RequestAttribute OrdersRequest request) {
        AssertUtil.nonNull(request.getOrdersId(), ResultEnum.NO_PARAM);

        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        List<OrdersInfoResponse> list = Lists.newArrayList();
        ResultModel<OrderDetailVo> resultModel = orderFeign.detail(OrderDetailDto.builder().orderId(request.getOrdersId()).build());
        AssertUtil.isTrue(resultModel);
        OrderDetailVo vo = resultModel.getData();

        Company2Dto company2Dto = companyBaseService.get2(vo.getCompanyId());
        Integer allNum = vo.getGoodsList().stream().mapToInt(OrderDetailVo.Goods::getSkuNum).sum();
        UserDto user = userAdminService.get(optUser.getUserId());
        BusinessCard card = businessCardBaseService.getByUserId(user.getUserId());

        list.add(OrdersInfoResponse.builder()
                .ordersId(vo.getOrderId())
                .ordersNo(vo.getOrderNo())
                .tradeNo(vo.getTradeNo())
                .orderPrice(MoneyUtil.getMoneyInt(vo.getOrderPrice()))
                .orderState(vo.getOrderState())
                .createTime(new Date(vo.getOrderCreateTime()))
                .payType(vo.getPayType())
                .payPrice(MoneyUtil.getMoneyInt(vo.getPayPrice()))
                .payTime(Objects.nonNull(vo.getOrderPayTime()) ? new Date(vo.getOrderPayTime()) : null)
                .deliveryType(vo.getDeliveryType())
                .remark(vo.getOrderRemark())

                .refundState(vo.getRefundState())
                .refundRemark(vo.getRefundRemark())

                .addressId(vo.getAddressId())
                .detailedAddress(vo.getAddressDetail())
                .receiveName(vo.getAddressName())
                .receivePhone(vo.getAddressPhone())

                .companyId(company2Dto.getCompanyId())
                .companyName(company2Dto.getCompanyName())

                .userId(user.getUserId())
                .logo(user.getUserImg())
                .name(user.getName())
                .phone(user.getPhone())
                .personalWx(Objects.nonNull(card) ? card.getPersonalWx() : null)

                .ordersModelList(ConvertUtils.list(vo.getGoodsList(), goods -> {
                    return OrdersInfoResponse.Goods.builder()
                            .goodsId(goods.getGoodsId())
                            .goodsName(goods.getGoodsName())
                            .photoUrl(goods.getGoodsPhoto())
                            .specAttribute(StringUtils.EMPTY)
                            .specName(goods.getSkuName())
                            .num(goods.getSkuNum())
                            .price(MoneyUtil.getMoneyInt(goods.getPrice()))
                            .allPrice(MoneyUtil.getMoneyInt(goods.getPrice().multiply(BigDecimal.valueOf(goods.getSkuNum()))))
                            .cardId(goods.getCardId())
                            .build();
                }))
                .allNum(allNum)
                .build());

        return ResultModel.success(list);
    }

    @ApiOperation(value = "撤销订单，确认发货")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ordersId", value = "订单id", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "orderState", value = "订单状态（1待付款，2待发货，3待收货，4已完成，5交易取消，6退款成功）", required = true, paramType = "Integer"),
    })
    @PostMapping("/updateOrderState")
    @ResponseBody
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel updateOrderState(@RequestAttribute OrdersRequest request) {
        if (OrderStateEnum.WAIT_RECEIVING.getCode().equals(request.getOrderState())) {
            ResultModel resultModel = orderFeign.send(OrderSendRequest.builder()
                    .orderId(request.getOrdersId())
                    .deliveryCompany(null)
                    .deliveryNo(null)
                    .build());
            AssertUtil.isTrue(resultModel);
        } else if (OrderStateEnum.CANCEL.getCode().equals(request.getOrderState())) {
            ResultModel resultModel = orderFeign.cancel(OrderCancelDto.builder()
                    .orderId(request.getOrdersId())
                    .build());
            AssertUtil.isTrue(resultModel);
        } else {
            AssertUtil.fail(ResultEnum.FAIL);
        }
        return ResultModel.success();
    }

    @ApiOperation(value = "修改订单退款状态1未申请，2退款申请中，3退款成功")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ordersId", value = "订单id", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "refundState", value = "退款状态1未申请(拒绝)，2退款申请中，3退款成功", required = true, paramType = "Integer"),
    })
    @PostMapping("/updateRefundState")
    @ResponseBody
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel updateRefundState(@RequestAttribute OrdersRequest request) {

        return crmFegin.updateRefundState(request);
    }

    @ApiOperation(value = "发货")
    @PostMapping("/send")
    @ResponseBody
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel send(@RequestAttribute OrdersSendRequest request) {

        return orderFeign.send(OrderSendRequest.builder()
                .orderId(request.getOrderId())
                .deliveryCompany(request.getDeliveryCompany())
                .deliveryNo(request.getDeliveryNo())
                .build());
    }

    /**
     * 导出
     */
    @GetMapping("download")
    @SecurityAuthCheck(company = true, card = true)
    public void download(@RequestAttribute OrdersRequest request, HttpServletResponse response) throws Exception {
        RequestContext.User user = RequestContextHolder.getRequestContext().getUser();
        OrderListPcRequest listPcRequest = OrderListPcRequest.builder()
                .companyId(user.getCompanyId())
                .orderState(request.getOrderState())
                .createTimes(request.getCreateTimes())
                .build();
        listPcRequest.setAll();
        ResultModel<OrderListPcResponse> responseResultModel = orderFeign.listPc(listPcRequest);
        AssertUtil.isTrue(responseResultModel);

        List<OrderDownloadResponse> downloadVoList = ConvertUtils.list(responseResultModel.getData().getPageInfo().getList(), order -> {
            return OrderDownloadResponse.builder()
                    .ordersNo(order.getOrdersNo())
                    .nickeName(order.getNickeName())
                    .phone(order.getPhone())
                    .address(order.getAddress())
                    .goodsName(order.getGoodsName())
                    .specAttribute(order.getSpecAttribute())
                    .orderPrice(order.getOrderPrice())
                    .createTime(order.getCreateTime())
                    .state(getState(order.getRefundState(), order.getOrderState()))
                    .deliveryCompany(order.getDeliveryCompany())
                    .deliveryNo(order.getDeliveryNo())
                    .build();
        });
        if (Objects.isNull(downloadVoList)) {
            downloadVoList = new ArrayList<>();
        }

        DownLoadExcelUtil.download(response, "订单列表", "订单", OrderDownloadResponse.class, downloadVoList);
    }

    private String getState(Integer refund, Integer state) {
        if (refund == 1) {
            return OrderStateEnum.getMessage(state);
        } else if (refund == 2) {
            return "退款中";
        } else if (refund == 3) {
            return "退款成功";
        } else {
            AssertUtil.fail("退款状态异常：" + refund);
        }
        return null;
    }
}
